#include "Col.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "PttyConnection.h"
#include "Class.h"
#include "File.h"
#include "System.h"

extern "C" int read(int, char*, int);

//---- PttyConnection ----------------------------------------------------------

NewMetaImpl(PttyConnection,Object, (TP(pttycon), T(mode), TE(state)));

PttyConnection::PttyConnection()
{
	pttycon= 0;
	mode= 0;
	state= eProcInited;
}

PttyConnection::~PttyConnection()
{
	SafeDelete(pttycon);
}

bool PttyConnection::Run(const char *name, const char **argv)
{
	mode= 0;
	pttycon= gSystem->MakePttyImpl();
	if (pttycon) {
		pttycon->SetPty(this);
		pttycon->SpawnSlave(name, argv);
		state= eProcRunning;
		return TRUE;
	}
	return FALSE;
}

void PttyConnection::Kill()
{
	SafeDelete(pttycon);
}

bool PttyConnection::IsRunning()
{
	return pttycon != 0;
}

int PttyConnection::Write(const char *buf, int n)
{
	int rc= -1;
	if (pttycon) {
		int fd= pttycon->GetFileNo();
		rc= File::Write(fd, buf, n);
		if (rc == -2) {
			pttycon->Flush();
			rc= File::Write(fd, buf, n);
		}
	}
	return rc;
}

int PttyConnection::Read(char *buf, int n)
{
	if (pttycon) {
		int rc= ::read(pttycon->GetFileNo(), buf, n);
		mode= pttycon->GetMode();
		return rc;
	}
	return -1;
}

void PttyConnection::BecomeConsole()
{
	if (pttycon)
		pttycon->BecomeConsole();
}

void PttyConnection::SetSize(const Point &cr)
{
	if (pttycon)
		pttycon->SetWinSize(cr);
}

void PttyConnection::DiedNotify()
{
	AbstractMethod("DiedNotify");
}

void PttyConnection::InputNotify()
{
	AbstractMethod("InputNotify");
}

void PttyConnection::ErrorNotify(int, const char*)
{
	AbstractMethod("ErrorNotify");
}

//---- PttyImpl ----------------------------------------------------------------

NewMetaImpl(PttyImpl,Object, (T(slavepid), T(masterfd), TP(pty)));

PttyImpl::PttyImpl()
{
	masterfd= -1;
	slavepid= -1;
	pty= 0;
}

PttyImpl::~PttyImpl()
{
	masterfd= -1;
	slavepid= -1;
	pty= 0;
}

void PttyImpl::ErrorNotify(int code, const char *msg)
{
	if (pty)
		pty->ErrorNotify(code, msg);
}

void PttyImpl::DiedNotify()
{
	if (pty)
		pty->DiedNotify();
}

int PttyImpl::SpawnSlave(const char*, const char**)
{
	return -1;
}

int PttyImpl::KillChild()
{
	return -1;
}

int PttyImpl::Flush()
{
	return -1;
}

int PttyImpl::GetMode()
{
	return -1;
}

int PttyImpl::BecomeConsole()
{
	return -1;
}

int PttyImpl::SetWinSize(const Point&)
{
	return -1;
}
